/*
 * PsCaster.h
 *
 *  Created on: 2016-8-24
 *      Author: zhengboyuan
 */

#ifndef PSCASTER_H_
#define PSCASTER_H_


////////////////////////////////////////////////////////////////////////////

#ifdef WIN32

    #ifndef NOMINMAX
    #define NOMINMAX
    #endif //NOMINMAX

	#include <Windows.h>
#else

#endif //WIN32


////////////////////////////////////////////////////////////////////////////

#ifdef _MSC_VER
    typedef signed char     int8_t;
    typedef unsigned char   uint8_t;
    typedef short           int16_t;
    typedef unsigned short  uint16_t;
    typedef int             int32_t;
    typedef unsigned        uint32_t;
    typedef long long       int64_t;
    typedef unsigned long long   uint64_t;
#else
    #include <stdint.h>
    typedef void*   HANDLE;
#endif //_MSC_VER


///////////////////////////////////////////////////////////////////
#ifdef WIN32
    #ifndef DLLEXPORT
    #define DLLEXPORT __declspec(dllexport)
    #endif //DLLEXPORT
#else
	#ifndef DLLEXPORT
    #define DLLEXPORT __attribute__ ((visibility ("default")))
	#endif //DLLEXPORT
#endif //WIN32

///////////////////////////////////////////////////////////////////
#ifdef __cplusplus
extern "C"
{
#endif

/////////////////////////////////////////////////////////////////////////////
#ifndef MKBETAG
#define MKBETAG(a,b,c,d) ((d) | ((c) << 8) | ((b) << 16) | ((unsigned)(a) << 24))
#endif //MKBETAG

#ifndef CASTER_TYPE
#define	CASTER_TYPE


/// 编码.
enum MCodec
{
	MCODEC_NONE = 0,

	MCODEC_H264 = 28,
	MCODEC_HEVC = 174, /// H.265
	MCODEC_H265 = MCODEC_HEVC,

	MCODEC_G711U = 65542,
	MCODEC_G711A,

	MCODEC_MP3 = 0x15001,
	MCODEC_AAC = 0x15002,
	MCODEC_AC3 = 0x15003,
	MCODEC_VORBIS = 0x15005,
    MCODEC_OPUS = 0x1503d,
	MCODEC_RAW = 0x10101010

};

enum MType
{
	MTYPE_NONE = -1,
	MTYPE_VIDEO = 0,
	MTYPE_AUDIO,
	MTYPE_DATA,
};


/// 媒体格式 
struct MFormat
{
	int codec;		/// 视频编码  @see MCodec
	int width;		/// 视频高 
	int height;		/// 视频宽 
	int framerate;		/// 帧率 
	int profile;
	int clockRate;  /// 时钟频率 

	int audioCodec;	/// 音频编码  @see MCodec
	int channels;	/// 通道数 
	int sampleRate;	/// 采样率 
	int audioProfile;	/// 档次 
	int audioRate;      /// 音频时钟频率 

	int vPropSize;		/// 视频解码参数, 对于H.264是sps+pps, 对于H.265是vps+sps+pps
	unsigned char* vProp;

	int configSize;		/// 音频解码参数, 如果是AAC编码, 则必须设置为AAC的config参数 
	unsigned char* config;

    int bitrate;    ///码率. 
    int audioBitrate;
};


/// 媒体包.
struct MPacket
{
	int type;       ///
	uint8_t* data;	/// 数据指针.
	int size;		/// 数据长度.
	int64_t pts;	/// 时间戳.
	int duration;	/// 时长.
	int flags;		/// 标识.
};


enum CasterConst
{
	MAX_CASTER = 64,
	INVALID_CASTER = -1
};


typedef int		caster_t;


enum CasterEventType
{
	CASTER_SESSION_REQUEST = 1,
	CASTER_SESSION_CREATE,
	CASTER_SESSION_DESTROY,
};

struct CasterEvent
{
	int  type;
	caster_t  handle;	/// 通道句柄.
	char name[256];		/// 通道名称.
};


/**
* 事件回调函数.
* @param event		事件.
* @param context	回调环境.
*/
typedef void(*CasterEventCallback)(const CasterEvent* event, void* context);


#endif //CASTER_TYPE


/// 协议类型.
enum PsCasterProtocol
{
	PSCASTER_PROTOCOL_NONE = 0,
	PSCASTER_PROTOCOL_UDP,
	PSCASTER_PROTOCOL_TCP,
	PSCASTER_PROTOCOL_RTP,		/// 基于UDP的RTP传输.
	PSCASTER_PROTOCOL_RTP_TCP	/// 基于TCP的RTP传输.
};

typedef int		pscaster_t;


struct PsCasterParams 
{
	uint8_t	payload;
	uint32_t ssrc;
	int es;				/// > 0 表示使用RTP传输ES流
};

enum PsCasterEventType
{

    CASTER_EVENT_CONNECTING = 0x11,
    CASTER_EVENT_CONNECTED,
    CASTER_EVENT_DISCONNECTED

};

typedef CasterEvent PsCasterEvent;

typedef CasterEventCallback PsCasterEventCallback;


/**
 * 初始化.
 * @return 0 表示成功.
 */
DLLEXPORT int pscaster_init();

/**
 * 反初始化.
 * @return
 */
DLLEXPORT int pscaster_quit();


/**
 * 打开发送通道.
 * @param handle	句柄.
 * @param protocol	传输协议, 暂支持UDP
 * @param outPort	本地端口.
 * @param fmt		媒体格式.
 * @return 0 表示成功.
 */
DLLEXPORT int pscaster_open(pscaster_t* handle, int protocol, int outPort, const MFormat* fmt);

/**
 * 关闭通道.
 * @param handle 通道句柄.
 */
DLLEXPORT void pscaster_close(pscaster_t handle);


/**
 * 添加发送目标.
 * @param handle 通道句柄.
 * @param ip		地址.
 * @param port		端口.
 * @return	0 表示成功.
 */
DLLEXPORT int pscaster_add_target(pscaster_t handle, const char* ip, int port);

/**
 * 删除发送目标.
 * @param handle	通道.
 * @param ip		地址.
 * @param port	端口.
 * @return 0 表示成功.
 */
DLLEXPORT int pscaster_remove_target(pscaster_t handle, const char* ip, int port);


/**
 * 删除所有的发送目标.
 * @param handle
 * @return
 */
DLLEXPORT int pscaster_remove_all_target(pscaster_t handle);


/**
 * 写媒体数据.
 * @param handle
 * @param pkt		媒体包.
 * @return
 */
DLLEXPORT int pscaster_write(pscaster_t handle, const MPacket* packet);


/**
 * 设置缓冲区最大时长, 单位为毫秒.
 * @param ms
 */
DLLEXPORT void pscaster_setQueueDuration(int ms);

/**
 * 设置socket发送缓冲区大小.
 * @param size
 */
DLLEXPORT void pscaster_setSendBufSize(int size);

/**
* 打开发送通道.
* @param handle	句柄.
* @param protocol	传输协议, 暂支持UDP
* @param outPort	本地端口.
* @param fmt		媒体格式.
* @return 0 表示成功.
*/
DLLEXPORT int pscaster_openEx(pscaster_t* handle, int protocol, int outPort, const MFormat* fmt, const PsCasterParams* params);


/**
 * 设置事件回调
 * @param handle    caster句柄
 * @param cb        回调函数
 * @param context   回调用户指针
 * @return 0 表示成功
 */
DLLEXPORT int pscaster_setEventCallback(pscaster_t handle, PsCasterEventCallback cb, void* context);


/**
 * 判断句柄是否有效, > 0 表示有效.
 */
DLLEXPORT int pscaster_isValid(pscaster_t handle);

/**
 * 允许/禁止重连
 * @param enabled > 0 表示允许
 */
DLLEXPORT void pscaster_enableReconnect(int enabled);

/**
* 设置TCP传输时前缀长度, 取值为2/4. 默认为4.
* @param size 前缀长度
*/
DLLEXPORT void pscaster_setTcpPrefixSize(int size);

/**
* 设置RTP包最大长度, 默认为 1160. 常规MTU值为1500时, RTP包最大值为: 1460.
* 在公网环境下, 该值建议在 900. 理论计算值 = mtu - 40 (IP+TCP头长度)
* @param size RTP包最大长度
*/
DLLEXPORT void pscaster_setRtpMaxSize(int size);


/////////////////////////////////////////////////////////////////////////////

#ifdef __cplusplus
}
#endif


#endif /* PSCASTER_H_ */
